/* 
 * File:   Clear.cpp
 * Author: Gab'z
 * 
 * Created on 31 mai 2012, 13:19
 */

#include "Clear.h"
#include "../../../memento/StackMemento.h"
#include "../../../Context.h"
#include "../../literal/Stack.h"

namespace calculator {

    Clear::Clear(const std::string name) : NullaryOperator(name) {
    }

    Clear::Clear(const Clear& orig) : NullaryOperator(orig._name) {
    }

    Clear::~Clear() {
    }

    Clear* Clear::clone() const {
        return new Clear(_name);
    }

    std::string Clear::isExecutable() const {
        if (Context::getInstance()->getCurrentStack()->empty()) return "Empty stack";
        return "";
    }

    const Memento* Clear::createMemento() const throw (CommandException) {
        return new StackMemento(clone(), Context::getInstance()->getCurrentStack()->clone());
    }

    void Clear::restoreFromMemento(const Memento* memento) const throw (MementoException) {
        const StackMemento* stackMemento = dynamic_cast<const StackMemento*> (memento);
        if (stackMemento == 0) {
            std::string str = "Bad Memento type, expected : StackMemento, was ";
            str += typeid (*memento).name();
            throw MementoException(str);
        }
        const Stack* stack = stackMemento->_stack;
        Context::getInstance()->getCurrentStack()->pop();
        for (int i = (int) stack->size() - 1; i >= 0; i--) {
            Context::getInstance()->getCurrentStack()->push(stack->getConstant(i));
        }
    }

    void Clear::eval(Stack* stack) const throw (CommandException) {
        Context::getInstance()->getCurrentStack()->clear();
    }

}
